package org.spring.bean.factory.support;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spring.bean.exceptions.BeansException;
import org.spring.bean.factory.BeanFactory;
import org.tool.core.lang.Assert;
import org.tool.reflect.ConstructorUtil;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 用于 BeanFactory 的简单对象实例化策略。
 * <p>
 * 不支持方法注入，尽管它为子类提供了覆盖以添加方法注入支持的钩子，例如通过覆盖方法。
 *
 * @author 李坤
 * @date 2022/4/21 17:10
 */
public class SimpleInstantiationStrategy implements InstantiationStrategy {

    private final Logger logger = LoggerFactory.getLogger(SimpleInstantiationStrategy.class);

    @Override
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory beanFactory) throws BeansException {
        logger.debug("开始实例化 bean：{}", beanName);

        Assert.hasText(beanName, "beanName must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        return ConstructorUtil.newInstance(beanDefinition.getBeanClass());
    }

    @Override
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory beanFactory,
                              Constructor<?> constructor, Object... args) throws BeansException {
        logger.debug("开始实例化bean：{}", beanName);

        Assert.hasText(beanName, "beanName must not be empty");
        Assert.notNull(constructor, "Constructor must not be null");

        Object bean;
        try {
            constructor.setAccessible(true);
            bean = constructor.newInstance(args);
        } catch (Exception exception) {
            logger.error("实例化 bean 失败：{}", beanName);
            throw new BeansException("Failed to instantiate bean");
        }

        return bean;
    }

    @Override
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory beanFactory,
                              Object factoryBean, Method factoryMethod, Object... args) throws BeansException {
        return null;
    }

}
